package com.zt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zt.mapper.BookingsMapper;
import com.zt.pojo.Bookings;
import com.zt.pojo.request.BookingRequest;
import com.zt.service.BookingsService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * 预约服务实现类
 */
@Service
public class BookingsServiceImpl extends ServiceImpl<BookingsMapper, Bookings> implements BookingsService {

    /**
     * 创建预约
     * @param request 预约请求
     * @param userId 用户ID
     * @return 预约ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer createBooking(BookingRequest request, Integer userId) {
        try {
            System.out.println("开始创建预约，用户ID: " + userId);
            System.out.println("预约请求数据: " + request);
            
            // 验证请求数据
            if (request == null) {
                throw new IllegalArgumentException("预约请求数据不能为空");
            }
            
            // 验证课程ID
            if (request.getCourseId() == null) {
                throw new IllegalArgumentException("课程ID不能为空");
            }
            
            if (request.getBookingDate() == null || request.getBookingDate().trim().isEmpty()) {
                throw new IllegalArgumentException("预约日期不能为空");
            }
            
            if (request.getTimeSlot() == null || request.getTimeSlot().trim().isEmpty()) {
                throw new IllegalArgumentException("时间段不能为空");
            }
            
            // 创建预约对象
            Bookings booking = new Bookings();
            booking.setUserId(userId);
            booking.setCourseId(request.getCourseId());
            booking.setKc(request.getKc());
            booking.setProvince(request.getProvince());
            booking.setCity(request.getCity());
            booking.setDistrict(request.getDistrict());
            booking.setGrade(request.getGrade());
            booking.setDetailedAddress(request.getDetailedAddress());
            try {
                // 解析日期
                System.out.println("尝试解析日期: " + request.getBookingDate());
                LocalDate bookingDate = LocalDate.parse(request.getBookingDate(), DateTimeFormatter.ISO_LOCAL_DATE);
                booking.setBookingDate(bookingDate);
            } catch (Exception e) {
                System.out.println("日期解析失败: " + e.getMessage());
                throw new IllegalArgumentException("预约日期格式不正确，应为yyyy-MM-dd格式");
            }
            
            booking.setTimeSlot(request.getTimeSlot());
            
            // 如果价格为空，设置默认价格
            if (request.getPrice() == null) {
                booking.setPrice(new java.math.BigDecimal("100"));
                System.out.println("价格为空，使用默认价格100");
            } else {
                booking.setPrice(request.getPrice());
            }
            
            booking.setStatus(0); // 默认状态为待支付
            booking.setCreateTime(LocalDateTime.now());
            booking.setUpdateTime(LocalDateTime.now());
            
            // 打印完整的预约对象数据
            System.out.println("准备保存的预约对象数据: " + booking);
            
            // 保存到数据库
            System.out.println("准备保存预约数据到数据库");
            save(booking);
            System.out.println("预约数据保存成功，ID: " + booking.getId());
            
            // 返回预约ID
            return booking.getId();
        } catch (Exception e) {
            System.out.println("创建预约过程中发生异常: " + e.getMessage());
            e.printStackTrace();
            throw e;
        }
    }
    
    /**
     * 获取用户的预约列表
     * @param userId 用户ID
     * @return 预约列表
     */
    @Override
    public List<Bookings> getUserBookings(Integer userId) {
        return baseMapper.getUserBookings(userId);
    }
    
    /**
     * 取消预约
     * @param bookingId 预约ID
     * @param userId 用户ID
     * @return 是否成功取消
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelBooking(Integer bookingId, Integer userId) {
        // 查询预约是否存在且属于当前用户
        LambdaQueryWrapper<Bookings> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Bookings::getId, bookingId)
                    .eq(Bookings::getUserId, userId);
        Bookings booking = getOne(queryWrapper);
        
        if (booking == null) {
            // 预约不存在或不属于当前用户
            return false;
        }
        
        // 只有状态为待支付(0)或已支付(1)的预约才能被取消
        if (booking.getStatus() != 0 && booking.getStatus() != 1) {
            return false;
        }
        
        // 更新预约状态为已取消(2)
        LambdaUpdateWrapper<Bookings> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Bookings::getId, bookingId)
                     .set(Bookings::getStatus, 2)
                     .set(Bookings::getUpdateTime, LocalDateTime.now());
        
        return update(updateWrapper);
    }

    /**
     * 获取用户的所有预约，按照状态过滤
     * @param userId 用户ID
     * @param status 状态，如果为null则返回所有状态
     * @return 预约列表
     */
    @Override
    public List<Bookings> getUserBookingsByStatus(Integer userId, Integer status) {
        LambdaQueryWrapper<Bookings> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Bookings::getUserId, userId);
        
        // 如果指定了状态，则按状态过滤
        if (status != null) {
            queryWrapper.eq(Bookings::getStatus, status);
        }
        
        queryWrapper.orderByDesc(Bookings::getCreateTime);
        
        return list(queryWrapper);
    }

    /**
     * 更新预约状态
     * @param bookingId 预约ID
     * @param status 新状态
     * @return 是否更新成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateBookingStatus(Integer bookingId, Integer status) {
        if (bookingId == null) {
            return false;
        }
        
        LambdaUpdateWrapper<Bookings> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Bookings::getId, bookingId)
                     .set(Bookings::getStatus, status)
                     .set(Bookings::getUpdateTime, LocalDateTime.now());
        
        return update(updateWrapper);
    }
} 